import MatchGameConfig from "./MatchGameConfig";
import SquareItem from "./SquareItem";

const { ccclass, property } = cc._decorator;
export enum SquareStateMachineState {
    normal = "normal",
    changing = "changing",
    dowing = "dowing",
    readyDestroy = "readyDestroy",
    destroy = "destroy"
}
declare var StateMachine: any;
@ccclass
class SquareStatusMgr {
    public static _instance: SquareStatusMgr;
    public squareFsm;

    public constructor() {
        this.squareFsm = this.getSquareFsm();
    }

    public static getInstance(): SquareStatusMgr {
        if (!this._instance) {
            this._instance = new SquareStatusMgr();
        }
        return this._instance;
    }

    public normalSquare(squareItem: any): void {
        if (!this.checkSquareItemEmpty(squareItem)) {
            this.initSquareStatus(squareItem);
            if (squareItem.getLightSpine()) {
                squareItem.getLightSpine().active = false;
            }
        }
    }

    public changeSquare(squareItem: SquareItem): void {
        if (this.checkSquareItemEmpty(squareItem)) {
            return;
        }
        if (squareItem.squareFsm.is(SquareStateMachineState.normal) && squareItem.canMove) {
            squareItem.squareFsm.changing();
        }
    }

    public changeSquareOver(squareItem: any): boolean {
        if (this.checkSquareItemEmpty(squareItem)) {
            return false;
        }
        if (squareItem.squareFsm.is(SquareStateMachineState.changing)) {
            squareItem.squareFsm.changeEnd();
        } else {
            console.error("交换的方块状态有问题", squareItem);
        }
        return true;
    }

    public dropSquare(squareItem: any): void {
        if (this.checkSquareItemEmpty(squareItem)) {
            return;
        }
        if (squareItem.squareFsm.is(SquareStateMachineState.normal) && squareItem.canMove) {
            squareItem.squareFsm.fall();
        }
    }

    public dropSquareFinish(squareItem: any): void {
        if (this.checkSquareItemEmpty(squareItem)) {
            return;
        }
        if (squareItem.canMove !== 0) {
            if (squareItem.squareFsm.is(SquareStateMachineState.dowing)) {
                squareItem.squareFsm.fallEnd();
            } else {
                console.error("Dowing----报错 canMove == false", squareItem);
                this.initSquareStatus(squareItem);
            }
        }
    }

    public readyDestorySquare(squareItem: any): void {
        if (this.checkSquareItemEmpty(squareItem)) {
            return;
        }
        if (squareItem.squareType === MatchGameConfig.SquareType.ObstacleItem && squareItem.squareItemInfo && squareItem.squareItemInfo.Hp < 0) {
            this.initSquareStatus(squareItem);
        } else if (squareItem.squareFsm.is(SquareStateMachineState.normal)) {
            squareItem.squareFsm.readyDestroy();
        } else {
            this.gotoState(squareItem, SquareStateMachineState.readyDestroy);
        }
    }

    public destorySquare(squareItem: any): void {
        if (this.checkSquareItemEmpty(squareItem)) {
            return;
        }
        if (squareItem.squareType === MatchGameConfig.SquareType.ObstacleItem && squareItem.squareItemInfo && squareItem.squareItemInfo.Hp < 0) {
            return;
        }
        if (squareItem.squareFsm.is(SquareStateMachineState.readyDestroy)) {
            squareItem.squareFsm.destroy();
        } else {
            this.gotoState(squareItem, SquareStateMachineState.destroy);
        }
    }

    public setNormalByDestory(squareItem: any): void {
        if (this.checkSquareItemEmpty(squareItem)) {
            return;
        }
        if (squareItem.squareFsm.is(SquareStateMachineState.readyDestroy)) {
            squareItem.squareFsm.clearReadyDestroy();
        }
    }

    public getSquareStatus(squareItem: any): string {
        if (this.checkSquareItemEmpty(squareItem)) {
            return "";
        }
        return squareItem.squareFsm.state;
    }

    public getSquareNormalStatus(squareItem: any): boolean {
        if (this.checkSquareItemEmpty(squareItem)) {
            return false;
        }
        return squareItem.squareFsm.is(SquareStateMachineState.normal);
    }

    public getSquareChangeStatus(squareItem: any): boolean {
        if (this.checkSquareItemEmpty(squareItem)) {
            return false;
        }
        return squareItem.squareFsm.is(SquareStateMachineState.changing);
    }

    public getSquareDropStatus(squareItem: any): boolean {
        if (this.checkSquareItemEmpty(squareItem)) {
            return false;
        }
        return squareItem.squareFsm.is(SquareStateMachineState.dowing);
    }

    public getSquareReadyDestoryStatus(squareItem: any): boolean {
        if (this.checkSquareItemEmpty(squareItem)) {
            return false;
        }
        return squareItem.squareFsm.is(SquareStateMachineState.readyDestroy);
    }

    public getSquareDestoryStatus(squareItem: any): boolean {
        if (this.checkSquareItemEmpty(squareItem)) {
            return false;
        }
        return squareItem.squareFsm.is(SquareStateMachineState.destroy);
    }

    public initSquareStatus(squareItem: any): void {
        if (this.checkSquareItemEmpty(squareItem)) {
            return;
        }

        squareItem.squareFsm.init = SquareStateMachineState.normal;
        squareItem.squareFsm.rest();
    }

    public gotoState(squareItem: any, state: string): void {
        if (this.checkSquareItemEmpty(squareItem)) {
            return;
        }
        squareItem.squareFsm.goto(state);
    }

    public checkSquareItemEmpty(squareItem: any): boolean {
        return !cc.isValid(squareItem);
    }

    public getSquareFsm() {
        const squareFsm = new StateMachine({
            init: SquareStateMachineState.normal,
            transitions: [
                { name: "changing", from: SquareStateMachineState.normal, to: SquareStateMachineState.changing },
                { name: "changeEnd", from: SquareStateMachineState.changing, to: SquareStateMachineState.normal },
                { name: "fall", from: SquareStateMachineState.normal, to: SquareStateMachineState.dowing },
                { name: "fallEnd", from: SquareStateMachineState.dowing, to: SquareStateMachineState.normal },
                { name: "readyDestroy", from: SquareStateMachineState.normal, to: SquareStateMachineState.readyDestroy },
                { name: "clearReadyDestroy", from: SquareStateMachineState.readyDestroy, to: SquareStateMachineState.normal },
                { name: "destroy", from: SquareStateMachineState.readyDestroy, to: SquareStateMachineState.destroy },
                { name: "clearDestroy", from: SquareStateMachineState.destroy, to: SquareStateMachineState.normal },
                { name: "rest", from: "*", to: SquareStateMachineState.normal },
                { name: "goto", from: "*", to: (state: string) => state }
            ],
            methods: {
                onNormal: function () { },
                onChanging: function () { },
                onDowing: function () { },
                onReadyDestroy: function () { },
                onDestroy: function () { }
            }
        });

        // cc.log("all state:", squareFsm.allStates());
        // cc.log("all transitions:", squareFsm.allTransitions());
        // cc.log("transitions:", squareFsm.transitions());

        return squareFsm;
    }
}

export default SquareStatusMgr.getInstance()